home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / MATHS / RLAB / RLAB125.ZIP / !RLaB / help_ai / function < prev    next >
Text File  |  1995-02-18  |  15KB  |  489 lines

  1. function:
  2.  
  3.     This help file covers several aspects of functions:
  4.  
  5.         1) Introduction
  6.  
  7.         2) Variable scoping
  8.  
  9.         3) Function arguments
  10.  
  11.         4) Function return values
  12.  
  13.         5) Function recursion
  14.  
  15.         6) Special topics        
  16.  
  17.     1) Introduction ------------------------------------------------
  18.  
  19.     Functions are an essential part of the language. Learning how
  20.     to create and use functions will greatly add to the benefits
  21.     of using RLaB. 
  22.  
  23.     It is important to remember that functions adhere to the RLaB
  24.     rule: "everything is a variable". Functions are variables, and
  25.     like the other types or classes of variables in RLaB can be
  26.     printed (although it will be hard to understand the output),
  27.     copied, and renamed. Functions cannot act as operands to
  28.     numeric operators, although the result of the function usually
  29.     can. Since function calls are evaluated "in-place" they can be
  30.     used within other expressions, for example:
  31.  
  32.     > sin(cos(1.0))
  33.         0.514
  34.  
  35.     > sin( [ cos(0.3), sqrt(cos(0.3)) ] )
  36.         0.817      0.829  
  37.  
  38.  
  39.     The syntax used for function definition is a little unusual...
  40.  
  41.     Example:
  42.  
  43.     > sum = function (s) 
  44.       {
  45.         local(i, Sum);
  46.         Sum = 0;
  47.         for(i in 1:size(s)) {
  48.           Sum = Sum + s[i];
  49.         }
  50.         return Sum;
  51.       };
  52.     >
  53.  
  54.     creates a function, and assigns it to the variable `sum'.
  55.     Sum is invoked like:
  56.  
  57.     > sum( [1,2,3,4,5] )
  58.         15
  59.  
  60.     2) Variable Scopes ---------------------------------------------
  61.  
  62.     When you start a RLaB session, either interactively or in
  63.     batch-mode, you create an environment. The environment or
  64.     workspace consists of the built-in functions, and any other
  65.     variables or functions you may have added. The workspace will
  66.     also be referred to as the global-symbol-table or the global
  67.     scope. 
  68.  
  69.     There are two other types of environment available: a
  70.     function's local environment and a file's static environment
  71.     (we will use the term environment and scope interchangeably).
  72.  
  73.     A function's local scope is temporary, it is created when the
  74.     function is invoked, and is destroyed when the function
  75.     returns. A file's static scope is created when the file is
  76.     loaded, and remains intact until the RLaB session is
  77.     terminated. 
  78.  
  79.     The different scopes serve to protect data from operations
  80.     that occur in the other scopes. There is some degree of
  81.     overlap in order to allow flexibility. Functions can affect
  82.     file-static and global scopes; statements within files can
  83.     affect statements within other files and the global
  84.     scope. More simply put, the "lower" scopes generally have
  85.     access to the "higher" scopes. When a variable is used, RLaB
  86.     uses certain rules to "bind" the variable. When we use the
  87.     term bind or bound, we mean that the variable name is
  88.     associated with an entry in one of the three types of symbol
  89.     tables.
  90.  
  91.     File-Scope: Variables that are in a file (but not within a
  92.             function) are bound to the global-symbol-table
  93.             (global-scope or global-environment) unless a
  94.             static declaration is used. When a variable is
  95.             declared static (see `help static') it is bound to
  96.             the file's symbol table. From that point on, the
  97.             variable will remain bound to the file's
  98.             scope. When a variable is declared static, it is
  99.             not visible from the global environment or from
  100.             any other files.
  101.  
  102.     Function Local Scope: In general, variables used within a
  103.             function (other than the function's arguments) are
  104.             bound to the function's local scope (there are
  105.             ways to override this behavior). Variables bound
  106.             to a function's local scope are not visible from a
  107.             file's scope or from the global scope. They are
  108.             created (undefined) when the function is invoked,
  109.             and destroyed when the function returns.
  110.  
  111.             There are exceptions: variables used in a function
  112.             context are bound to the global-symbol-table. For
  113.             example:
  114.  
  115.                 x = a * sin ( pi )
  116.  
  117.             `sin' is used in a function context, and is bound
  118.             to the global scope, while `x', `a', and`pi' are
  119.             bound to the function's local environment.
  120.  
  121.             Function's that are defined within a file have
  122.             full access to the file's static variables.
  123.             Function variables will be bound to the file's
  124.             scope before local binding occurs. For example:
  125.  
  126.             ---- beginning of file.r ----
  127.  
  128.             static (A, pi)
  129.             A = 1.e-3;
  130.             pi = atan(1)*4;
  131.  
  132.             fun = function ( a ) { return A*sin(pi*A*a); }
  133.  
  134.             ---- end of file.r ----
  135.  
  136.             When `fun' is created it binds `A' and `pi'
  137.             to file.r's static environment.
  138.  
  139.             There are two declarations: `global' and `local'
  140.             that can be used to override the default behavior
  141.             if necessary. Variables declared local will be
  142.             bound to to the function's local scope, and
  143.             variable declared global will be bound to the
  144.             global scope.
  145.  
  146.             **NOTE: There is one more special exception (for
  147.             advanced usage): Function variables can be
  148.             members of a list, or members of a list, that is a
  149.             member of another list, etc, etc... In effect this
  150.             allows users to hide or protect variables and
  151.             functions in an arbitrary manner. Thus, when RLaB
  152.             sees something like:
  153.  
  154.                 ML.e1.signal( a )
  155.  
  156.             it does not bind `ML' to the global scope. In this
  157.             context RLaB cannot bind the function until
  158.             runtime, so the list is by default bound to the
  159.             function's local scope. This behavior can be
  160.             changed by using the global, or static
  161.             declarations.
  162.             
  163.  
  164.     The built-in function fvscope performs a variable scope
  165.     analysis of any user-function. For example:
  166.  
  167.     ---- beginning of file.r ----
  168.     static (stat)        // Keep track of some statistic.
  169.     stat.n = 0;
  170.     stat.total = 0;
  171.  
  172.     x = function (a, b)
  173.     {
  174.       local (a)
  175.       global (pi)
  176.  
  177.       for( i in 1:a.nr ) 
  178.       {
  179.         a[;i] = a[;i]*norm(a);
  180.       }
  181.       retv = 2*pi*norm(a)*b;
  182.       stat.n = stat.n + 1;
  183.       stat.total = stat.total + retv;
  184.  
  185.       return << val = retv; avg = stat.total/stat.n >>;
  186.     };
  187.     ---- end of file.r ----
  188.  
  189.     > local ("./file.r");
  190.     > fvscope(x);
  191.         Function Variable SCOPE analysis for : x
  192.         Filename: ./jnk.r
  193.     
  194.         line    GLOBAL            ARG        LOCAL
  195.     
  196.           10                        Local-Var: i
  197.           10                        Local-Var: a
  198.           12                        Local-Var: a
  199.           12                        Local-Var: i
  200.           12                        Local-Var: a
  201.           12                        Local-Var: i
  202.           12                        Local-Var: a
  203.           12    Global-Var: norm
  204.           14                        Local-Var: retv
  205.           14    Global-Var: pi*
  206.           14                        Local-Var: a
  207.           14    Global-Var: norm
  208.           14                Arg-Var: b
  209.           15    Static-Var: stat
  210.           15    Static-Var: stat
  211.           16    Static-Var: stat
  212.           16    Static-Var: stat
  213.           16                        Local-Var: retv
  214.           17                        Local-Var: retv
  215.           17    Static-Var: stat
  216.           17    Static-Var: stat
  217.     
  218.     The function `x' is used to compute some arbitrary value. The
  219.     list `stat' is used to keep track of how many times `x' is
  220.     called, and to compute the average of the return
  221.     value. fvscope shows us, line by line, each variable, and how
  222.     it is bound.
  223.  
  224.     3) Function arguments ------------------------------------------
  225.  
  226.     RLaB supports both "pass by reference" and "pass by value" for
  227.     passing arguments to a function. 
  228.  
  229.     Pass by reference means that the arguments, while still
  230.     referred to be there declared names, are in fact bound to the
  231.     caller's scope. Thus, the function can directly modify
  232.     variables in the caller's scope.
  233.  
  234.     Pass by value means that a function cannot modify variables in
  235.     the caller's scope - essentially, an argument that is passed
  236.     by value is copied, and the copied value is passed to the
  237.     function to operate on.
  238.  
  239.     Pass by reference can be considered the default behavior,
  240.     since it takes no special effort on the user's part. Pass by
  241.     value is achieved by declaring function arguments to be
  242.     local. For example:
  243.  
  244.     // Pass by reference
  245.  
  246.     > myf = function ( A ) { A = "changed"; return A; }
  247.         <user-function>
  248.     > B=10;
  249.     > myf(B);
  250.     > B
  251.      B =
  252.     changed
  253.  
  254.     // Pass by value
  255.     > myf = function ( A ) { local (A) A = "changed"; return A; }
  256.         <user-function>
  257.     > B=10;
  258.     > myf(B);
  259.     > B
  260.      B =
  261.            10
  262.  
  263.     In the previous example B, a variable in the global workspace,
  264.     is changed by myf (pass by reference). In the second part of
  265.     the example, the function argument A, is redeclared to be
  266.     local. This redeclaration forces the function argument to be
  267.     passed by value.
  268.  
  269.     One advantage of this behavior is that users can create
  270.     functions and selectively decide which variables should be
  271.     passed by reference, and which should be passed by value.
  272.  
  273.                 * * *
  274.  
  275.     You do not have to call a function with the same number of
  276.     arguments specified in the definition. If you invoke a
  277.     function with more arguments than declared, the result is an
  278.     error. If you call the function with less arguments than
  279.     declared, RLaB will pad the argument list with UNDEFINED,
  280.     objects. Additionally, commas may be used to "skip" arguments
  281.     that are unnecessary. for each argument that is "skipped" an
  282.     UNDEFINED variable is passed to the function during execution.
  283.  
  284.     UNDEFINED arguments can be detected with the exist function,
  285.     for example: 
  286.  
  287.           if (!exist (ARG))
  288.           {
  289.             ARG = 0;    // Initialize undefined argument
  290.           }
  291.     
  292.     The function-local variable `nargs' is automatically
  293.     initialized to the argument number of the last specified
  294.     argument in the function call. For example:
  295.  
  296.     testf = function ( a, b, c, d, e )
  297.     {
  298.       nargin
  299.     }
  300.  
  301.     > testf ( 1 , 2 );
  302.             2
  303.     > testf ( 1 , , 2 );
  304.             3
  305.     > testf ( 1 , , 2, 3 );
  306.             4
  307.  
  308.                 * * *
  309.  
  310.     Lists can be used to get the effect of variable argument
  311.     lists. If you are not familiar with lists, then now would be a
  312.     good time to `help LIST'. A function can take a list as an
  313.     argument and then pull the actual number of list elements, and
  314.     their values, from the list when the function is called. For
  315.     example:
  316.  
  317.     > vlistf = function( l )
  318.       {
  319.         local(i,x);
  320.  
  321.         printf( "number of elements in variable arg-list = %i\n", size(l) );
  322.       
  323.         // Pull each element from the list
  324.       
  325.         for( i in 1:size(l) )
  326.         {
  327.           x = l.[i];
  328.           // now do something with x
  329.         }
  330.       };
  331.     > vlistf( << "string"; [1,2;3,4] >> )
  332.     number of elements in variable arg-list = 2
  333.     
  334.                 * * *
  335.  
  336.     Functions can take other functions as arguments, for example:
  337.  
  338.     > trick = function ( a , b )
  339.       {
  340.         a(b)
  341.       };
  342.     > trick( eye, [3,3] );
  343.      matrix columns 1 thru 3
  344.                1           0           0
  345.                0           1           0
  346.                0           0           1
  347.  
  348.     Note that the function name, passed as an argument, did not
  349.     need quotes. This is so because functions are variables in the
  350.     same sense as scalars, strings, and matrices. The variable a
  351.     in the previous function example refers to the function eye,
  352.     since function args are passed by reference.
  353.  
  354.     4) Function return values --------------------------------------
  355.  
  356.     All functions return a value, although the return statement is
  357.     optional. If a return statement is not used, then the function
  358.     will return 0 (zero) to the calling environment. If the return
  359.     statement is used, the result of the return statement is
  360.     passed back to the calling environment.
  361.  
  362.     Functions can only return a single entity to the calling
  363.     environment. If it is necessary to return more than one
  364.     entity, a list can be used to group multiple entities together
  365.     for return.
  366.  
  367.     Example:
  368.  
  369.     We want to write a function that creates a set of matrices (a
  370.     state-space model). We will write such a function, and group
  371.     the separate matrices together in a list.
  372.  
  373.     > ss = function( w )
  374.       {
  375.          local(A, B, n);
  376.         n = size( w )[1];
  377.         A = [ zeros(n,n), eye(n,n);
  378.               -w;         zeros(n,n) ];
  379.         B = ones(n,n);
  380.      
  381.          return << A = A; B = B >>;
  382.       };
  383.     >
  384.  
  385.     The return statement creates the list, and assign the names
  386.     `A' and `B' to it's members.    
  387.  
  388.     Since functions are evaluated "in-place" their return values
  389.     can be manipulated in the usual ways, for example:
  390.  
  391.     > eig(symm(rand(3,3))).val
  392.      val =
  393.        -0.937      0.571       1.81  
  394.  
  395.     > eig(symm(rand(3,3))).val[2]
  396.         0.191
  397.  
  398.     > rand(10,10)[1,3,5;2,4,6]
  399.          0.29      0.411      0.345  
  400.         0.561      0.686     0.0287  
  401.         0.269      0.324       0.57  
  402.  
  403.     5) Function recursion ------------------------------------------
  404.  
  405.     Functions can call themselves recursively. For a function to
  406.     call itself recursively, the special keyword `$self' must be
  407.     used. `$self' must be used because the statements within a
  408.     function are compiled before the function is assigned to a
  409.     variable. Therefore, the function cannot resolve a recursive
  410.     reference without `$self'.
  411.  
  412.     Example:
  413.  
  414.     > fact = function (f) 
  415.       {
  416.         if(f <= 1) {
  417.           return 1;
  418.         else
  419.           return f*$self(f-1);
  420.         }
  421.       };
  422.     > fact(10)
  423.         3628800
  424.  
  425.     The local statement in the previous function makes `a' local
  426.     to the function `x'. Since `a' is also a function argument, it
  427.     is copied into the local variable `a', which is used for the
  428.     throughout the function. As you can see `a' does not even show
  429.     up as an argument variable in the output from fvscope. 
  430.  
  431.     Since `i' is not explicitly declared, it defaults to a local
  432.     variable with initial value undefined. When the function
  433.     returns the variable `i' (and all other local variables) will
  434.     cease to exist. When x() is called again `i' (and all other
  435.     local variables) will again be re-initialized undefined. The
  436.     local statement must be the 1st statement in a function, and
  437.     only one local statement is allowed. If you must declare alot
  438.     of local variables, then break the local statement with a
  439.     continuation. Note that `norm', although undeclared, is a
  440.     global variable. This is because `norm' is a function. Since
  441.     functions cannot be entirely local to another function it
  442.     makes no sense to have to declare all functions global.
  443.  
  444.     The global statement tells the function to get `pi' from the
  445.     global workspace. The global statement must follow the local
  446.     statement, and precede any executable function statements.
  447.  
  448.     6) Special Topics ----------------------------------------------
  449.  
  450.         A) Although pass by reference is the default behavior
  451.         for function arguments, there are some instances where
  452.         this may not seem true (but it is). For example, when
  453.         you pass part of a matrix into a function you cannot
  454.         modify the original matrix.
  455.  
  456.         > x = function ( a ) { global (pi) a[1] = pi; }
  457.             <user-function>
  458.         > z=rand(2,2);
  459.         > z
  460.          z =
  461.            0.0369      0.665  
  462.             0.162     0.0847  
  463.         > x(z);
  464.         > z
  465.          z =
  466.              3.14      0.665  
  467.             0.162     0.0847  
  468.         > x(z[2]);
  469.         > z
  470.          z =
  471.              3.14      0.665  
  472.             0.162     0.0847  
  473.         > y
  474.             UNDEFINED
  475.         > x(y=z[2]);
  476.         > y
  477.          y =
  478.              3.14  
  479.  
  480.         You can see that in the first function call, z is
  481.         passed by reference. In the second call, the second
  482.         element of z (z[2]) is copied into a temporary
  483.         variable, which in turn is passed by reference to the
  484.         function. In the last call the temporary variable is
  485.         stored in the variable y, which as you can see, is
  486.         passed by reference to the function for modification.
  487.  
  488.     ----------------------------------------------------------------
  489.